API Testing & Broken Access Control
9.6.1 - APIs
APIs enable software systems and applications to communicate and share data. API testing is important a vulnerabilities in APIs can undermine core aspects of a site's confidentiality, integrity and availability.
All dynamic sites are composed of APIs so classic vulns like SQLi can be classed as API testing. Testing APIs on the front end with a focus on RESTful and JSON APIs is the goal here.
Look at the attack surface first. Identify API endpoints, i.e. where an API receives requests about a specific resource on the server.
The API endpoint is /api/books here. This results in interaction with the API to retrieve a list of books from another library. Another endpoint might be /api/books/mystery, retrieving a list of mystery books.
Once the endpoints have been identified, you need to test how you interact with them, enabling you to construct valid HTTP requests to the API.
- What input data does the API process? What's compulsory and what's optional?
- What request types are accepted?
- Rate limits and authentication mechanisms?
What makes an API RESTful?
| Feature | RESTful API | Non-RESTful API (e.g., RPC, SOAP, GraphQL) |
|---|---|---|
| Protocol | HTTP | Can be HTTP, TCP, gRPC, SOAP, etc. |
| Interface | Uniform (GET /users) |
Custom calls (loginUser(), fetchData()) |
| Data Format | JSON (usually) | XML, binary, JSON, etc. |
| Methods | Standard HTTP (GET, POST, etc.) |
Often just POST (e.g., SOAP) |
| Stateless | Yes | Not always |
| URL Structure | Resource-based (/users/123) |
Function-based (/getUser?id=123) |
| ## 9.6.2 - API Documentation | ||
| Crawl the API with burp or ZAP. |
Look for endpoint that may refer to API documentation for relatively low-hanging fruit.
If you identify an endpoint resource, make sure to investigate the base path, I.e. identifying a resource endpoint like /api/swagger/v1/users/123. Investigate the directory levels.
/api/swagger/v1/api/swgger/api/swagger
9.6.3 - Machine Readable Documentation
Check out automated tools to analyze any machine-readable API documentation you find.
- Burp scanner to crawl and audit. - https://mafiaguy.medium.com/how-to-use-burp-suite-rest-api-5c3ec059a6ad
- OpenAPI Parser BApp for OpenAPI
- Postman or SoapUI for specialised testing of documented endpoints. - https://www.postman.com/api-platform/api-testing/
9.6.4 - Identifying API Endpoints
Look for patterns in ZAP/Burp scanner that suggest API endpoints in the URL structure, such as /API/. Look for JS files too as these contain references to API endpoints that you haven't triggered directly via the web browser. Burp scanner auto-extracts some endpoints during crawls but for a more heavyweight extraction, use the JS Link Finder BApp.
9.6.5 - Interacting with API Endpoints
Use the repeater & intruder and check the following;
- How does the API respond to changing HTTP method and media type?
- Do error messages change at all?
- What changes in the response header and response code?
Oftentimes, these include information that can be used to construct a valid HTTP request.
GETto retrieve datePATCHto apply partial changes to a resourceOPTIONSto retrieve information on types of request methods that can be used on a resource.
An API endpoint may support different HTTP methods and it's therefore important to test all potential methods when investigating them. This may enable identification of more endpoint functionality.
I.e. /api/tasks may support
GET /api/tasks- retrieve a list of tasksPOST /api/tasks- create a new taskDELETE /api/tasks/1- delete a task
9.6.6 - PortSwigger - Exploiting an API Endpoint
An API endpoint may support different HTTP methods. It's therefore important to test all potential methods when you're investigating API endpoints. This may enable you to identify additional endpoint functionality, opening up more attack surface.int with Documentation**
Trawling through the site and logging in with our user gives us some js code. This was done by turning on the proxy, leaving the interceptor off and analysing the HTTP history.
Note the fetch method (code uses another endpoint to make this request happen). We can see it uses the PATCH method containing the email address.
It's worth inspecting the endpoint from which the initial request came from. It's likely it'll show the API we're looking for. In this case, we can also find API endpoints dirbusting. Note how this is a completely different endpoint to the js function.
Changing our email gets us a valid API endpoint.
Removing the email value and changing the user gives us a different users' information. This is a broken access control exploit, more specifically IDOR. Tested both with and without the valid user cookie (with worked as shown).
Documentation was found with dirbusting and was at the /api/ endpoint.
Testing this with the DELETE request shows our exploit vector.
9.6.7 - PortSwigger - Finding & Exploiting an Unused API Endpoint
You can also gather a lot of information by browsing applications that use the API. This is often worth doing even if you have access to API documentation, as sometimes documentation may be inaccurate or out of date.
While browsing the application, look for patterns that suggest API endpoints in the URL structure, such as /api/. Also look out for JavaScript files.
Trawling the site and clicking on some products, gets us some api endpoints
No other API connection or anything interesting higher up the directory
Noticed when changing from GET to POST we get this
PATCH gets some interesting results, showing we need a particular content type in it's request header. Adding this to the request header, and including empty json brackets so the content-type header has something to chew on gives us an error message looking for a "price" parameter.
Modifying the price here, modifies it on the front end (as confirmed when checking).
9.6.8 - PortSwigger - Exploiting a Mass Assignment Vulnerability
Once you have identified some initial API endpoints, you can use Intruder to uncover hidden endpoints. For example, consider a scenario where you have identified the following API endpoint for updating user information:
PUT /api/user/update
When doing API recon, you may find undocumented parameters that the API supports. You can attempt to use these to change the application's behaviour.
Mass assignment (also known as auto-binding) can inadvertently create hidden parameters. It occurs when software frameworks auto-bind request parameters to fields on an internal object. Mass assignment may therefore result in the application supporting parameters that weren't ever intended to be processed by the developer.
Digging through the site again, we come across an API endpoint on the checkout. This shows some values in the response. Can any of these parameters be modified is our question in mass assignment.
Testing out multiple variations of values with a POST request. A lot of these get 201 created codes with an error in the body. We're looking for a valid response with no errors basically.
After a few tests. we get a response (albeit one with no body) but with no header showing insufficient funds in the location parameter. After overcoming this hurdle, editing the percentage value on the POST request to 200 gave us an invalid percentage error. This is a very good sign.
Modifying this to a valid value of 100, caused the parameter to update, show an order confirmation value set to true in the location header and essentially send the percentage_value back to the site. This updated the value of the jacket to 0 as per the 100% discount.
9.6.7 - Broken Access Control (A Very Basic Example)
This query parameter (user) returns the balance of different users (API). The session cookie should not be allowing for this information to be retrieved from the API.
Removing the cookie from the request also gives us the same answer, this means any web user (unauthenticated) can view sensitive information about any user just by knowing their usernames.
This would be what it would look like if authentication was properly working. It would 302 redirect to the login page, should the session cookie get omitted.
Check headers with curl
curl -v http://example.com
9.6.8 - Exploiting Server-Side Parameter Pollution in a Query String
POST request on login screen (creds administrator:administrator and a CSRF value as query params). This doesn't look like an API on it's own but it's worth looking at later as it's a query parameter.
The more interesting endpoint is the one ending in .js that is uncovered when requesting a password reset as administrator (doesnt have to be this user, regardless)
This is the most interesting one as we can analyze the JS.
What we can see is the function that takes in the username input.
We also see the invalid username error catch function
API Security - DVWA - Low
We're aiming to look at the call used to create this table and if it can be exploited to return some additional information.
We see in the inspect tab and the browser URL bar that the api version is v2, maybe we can change this to v1?
This exposes hashes, in what is clearly a development version
Didn't even need hashcat for these
